using System;
using System.Collections;
using System.Collections.Generic;
using PEProtocol;
using PEUtils;
using UnityEngine;

public class PERoot : MonoSingleton<PERoot>
{
    //Service
    private TimeSvc mTimeSvc;
    private ResSvc mResSvc;
    private NetSvc mNetSvc;
    private UISvc mUISvc;
    private AudioSvc mAudioSvc;
    private EvtSvc mEvtService;
    private List<ILogic> mServices = new List<ILogic>();

    public NetSvc NetService { get { return mNetSvc; } }
    public UISvc UIService { get { return mUISvc; } }
    public ResSvc ResService { get { return mResSvc; } }
    public AudioSvc AudioService { get { return mAudioSvc; } }
    public AcctSystem AcctSystem { get { return mAcctSystem; } }
    public EvtSvc EvtService { get { return mEvtService; } }


    //System
    private AcctSystem mAcctSystem;
    private StageSystem mStageSystem;
    private List<ILogic> mSystems = new List<ILogic>();

    private CPlayMode mCurMode;
    private Dictionary<CPlayMode, BaseMode> mModeDic = new Dictionary<CPlayMode, BaseMode>();

    void Start()
    {
        DontDestroyOnLoad(gameObject);
        InitLog();
        InitSvc();
        InitMode();
        InitSystem();
    }

    public void InitLog()
    {
        LogConfig config = new LogConfig()
        {
            enableLog = true, //是否开启日志
            logPrefix = "", //日志前缀
            enableTime = true, //是否开启时间
            logSeparate = ">", //分隔符
            enableThreadID = true, //是否开启线程ID
            enableTrace = true, //是否启用堆栈信息
            enableSave = true, //是否保存
            enableCover = true, //保存的时候是否覆盖掉
            saveName = "MMOClientLog.txt",
            loggerEnum = LoggerType.Unity
        };
        PELog.InitSettings(config);
        this.Log("PERoot Init...");
    }

    public void InitSvc()
    {
        mTimeSvc = new TimeSvc();
        mServices.Add(mTimeSvc);
        mResSvc = new ResSvc();
        mServices.Add(mResSvc);
        mEvtService = new EvtSvc();
        mServices.Add(mEvtService);
        mNetSvc = new NetSvc();
        mServices.Add(mNetSvc);
        mUISvc = new UISvc();
        mServices.Add(mUISvc);
        mAudioSvc = new AudioSvc();
        mServices.Add(mAudioSvc);

        foreach (var service in mServices)
        {
            service.Init();
        }
    }

    public void InitSystem()
    {
        mAcctSystem = new AcctSystem();
        mSystems.Add(mAcctSystem);
        mStageSystem = new StageSystem();
        mSystems.Add(mStageSystem);
        foreach (var system in mSystems)
        {
            system.Init();
        }
        
        mStageSystem.EnterGameStage(1, () =>
        {
            EnterGameMode(CPlayMode.Login);
        });
    }
    

    private void Update()
    {
        for (int i = 0; i < mServices.Count; i++)
        {
            mServices[i].Tick();
        }

        for (int i = 0; i < mSystems.Count; i++)
        {
            mSystems[i].Tick();
        }
        if (mCurMode != CPlayMode.None)
        {
            mModeDic[mCurMode].Update();
        }

       
    }

    private void OnApplicationQuit()
    {
        for (int i = mServices.Count-1; i >= 0; i--)
        {
            mServices[i].UnInit();
        }

        for (int i = mSystems.Count-1; i >= 0; i--)
        {
            mSystems[i].UnInit();
        }
    }

    #region Mode

    public void InitMode()
    {
        mModeDic.Add(CPlayMode.Login, new LoginMode());
        mModeDic.Add(CPlayMode.Create, new CreateMode());
        mModeDic.Add(CPlayMode.Major, new MajorMode());
        mModeDic.Add(CPlayMode.Wild, new WildMode());
     
    }

    public void EnterGameMode(CPlayMode mode)
    {
        if (mModeDic.ContainsKey(mode))
        {
            if (mCurMode != CPlayMode.None)
            {
                mModeDic[mCurMode].Exit();
            }
        }
        mCurMode = mode;
        mModeDic[mCurMode].Enter();
    }

    public void ExitGameMode(CPlayMode mode)
    {
        if (mode != CPlayMode.None)
        {
            mModeDic[mCurMode].Exit();
        }
        mCurMode = CPlayMode.None;
    }

    #endregion
}